package com.jing.tong.asm.service;

import com.jing.tong.asm.dto.ShiroUser;
import com.jing.tong.asm.sys.service.UserService;
import com.jing.tong.asm.util.Encodes;
import com.jing.tong.asm.sys.domain.User;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.PostConstruct;

/**
 * <p> </p>
 *
 * @author sog
 * @version 1.0
 * @since JDK 1.7
 */
public class ShiroRealm extends AuthorizingRealm {

    public static final String HASH_ALGORITHM = "SHA-1";
    public static final int HASH_INTERATIONS = 1024;
    @Autowired
    private UserService userService;

    /**
     * 设定Password校验的Hash算法与迭代次数.
     */
    @PostConstruct
    public void initCredentialsMatcher() {
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(HASH_ALGORITHM);
        matcher.setHashIterations(HASH_INTERATIONS);

        setCredentialsMatcher(matcher);
    }


    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }

    /**
     * 认证信息.(身份验证)
     *
     * @param authcToken 是用来验证用户身份
     * @return 登录身份
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
        String name = token.getUsername();

        // 从数据库获取对应用户名密码的用户

        User userByName = userService.findByUserName(name);
        if (userByName == null) {
            throw new UnknownAccountException("账户不存在！");
        }
        byte[] salt = Encodes.decodeHex(userByName.getSalt());
        final ShiroUser principal = new ShiroUser(userByName.getUsername(), userByName.getPhone());
        final ByteSource credentialsSalt = ByteSource.Util.bytes(salt);
        final String userByNamePassword = userByName.getPassword();
        return new SimpleAuthenticationInfo(principal, userByNamePassword, credentialsSalt, getName());
    }
}
